#include "date.h"

using namespace std;
using namespace aviation;

//Constructors

Date::Date()
{
	m_day = 1;
	m_month = 1;
	m_year = 2000;
}

Date::Date(const String& fcgString)
{
	//Check that the length of the date is 8
	if(fcgString.length() != 8) throw exception("Attempted to instantiate a Date object with a string that does not consist of 8 characters."); 

	char d1 = fcgString[0];
	char d2 = fcgString[1];
	char m1 = fcgString[2];
	char m2 = fcgString[3];
	char y1 = fcgString[4];
	char y2 = fcgString[5];
	char y3 = fcgString[6];
	char y4 = fcgString[7];

	//Check that the input is a valid date. 
    if(!(d1 >= '0' && d1 <= '3')) throw exception("The first digit of the date is not valid.");
	if(d1 == '3') { if(!(d2 >= '0' && d2 <= '1')) throw exception("The second digit of the date is not valid."); }
    if(!(d2 >= '0' && d2 <= '9')) throw exception("The second digit of the date is not valid.");
	if(!(m1 >= '0' && m1 <= '1')) throw exception("The third digit of the date is not valid.");
	if(m1 == '1') { if(!(m2 >= '0' && m2 <= '2')) throw exception("The fourth digit of the date is not valid."); } 
	if(!(m2 >= '0' && m2 <= '9')) throw exception("The fourth digit of the date is not valid.");
	//The year must be in the range 2000 to 2099.
	if (y1 != '2') throw exception("The fifth digit of the date is not valid.");
	if (y2 != '0') throw exception("The sixth digit of the date is not valid.");
	if (!(y3 >= '0' && y3 <= '9')) throw exception("The seventh digit of the date is not valid.");
	if (!(y4 >= '0' && y4 <= '9')) throw exception("The eighth digit of the date is not valid.");

	//Convert the string into integers.
	const unsigned int asciiOffset = 48;
	m_day = 10*(d1-asciiOffset) + (d2-asciiOffset);
	m_month = 10*(m1-asciiOffset) + (m2-asciiOffset);
	m_year = 1000*(y1-asciiOffset) + 100*(y2-asciiOffset) + 10*(y3-asciiOffset) + (y4-asciiOffset);

	//Validate the number of days in month.
	const unsigned int days[12] = {31, 28, 31, 31, 31, 30, 31, 31, 30, 31, 30, 31};
	const unsigned int maxDays = days[m_month-1];
	if(m_day > maxDays) throw exception("Error: Invalid number of days for this month.");
}

Date::Date(const Date& other)
{
	*this = other;
}

Date::~Date()
{
}

//Operators

Date& Date::operator=(const Date& other)
{
	m_day = other.m_day;
	m_month = other.m_month;
	m_year = other.m_year;

	return *this;
}

const bool Date::operator==(const Date& other) const
{
	return m_day == other.m_day && m_month == other.m_month && m_year == other.m_year;
}

const bool Date::operator!=(const Date& other) const
{
	return !(*this == other);
}

const bool Date::operator<(const Date& other) const
{
	return m_year < other.m_year 
		|| m_year == other.m_year && m_month < other.m_month 
		|| m_year == other.m_year && m_month == other.m_month && m_day < other.m_day;
}

//Accessors

const unsigned int Date::GetDay() const
{
	return m_day;
}

const unsigned int Date::GetMonth() const
{
	return m_month;
}

const unsigned int Date::GetYear() const
{
	return m_year;
}

const std::string Date::AsString() const
{
	String s1 = util::XtoA(m_day, 2, '0');
	String s2 = util::XtoA(m_month, 2, '0');
	String s3 = util::XtoA(m_year, 4, '0');
	return (s1+s2+s3);
}